class GossipNode extends Node {
  var nOfRumors = 0
  val timer = new java.util.Timer();
  
  def receive = {
    case SetNeighbours(n:Int, t:Int) =>
      {
          if (t == Networks.LineNetwork)
          {
            this.loadLineNeighbours(n)
          }
          else if (t == Networks.GridNetwork)
          {
            this.loadGridNeighbours(n)
          }
          else if (t == Networks.ImperfectGridNetwork)
          {
            this.loadImperfectGridNeighbours(n)
          }
          
          sender ! LoadedNeighbours
    	  //println("Set up done for: " + self.path.name)
      }
    case Rumor => 
      {
        if (nOfRumors < Main.rumorLimit)
        {
			if (nOfRumors == 0){
			    //println("got message: " + self.path.name)
			    Main.NoOfActorsThatGotMessage += 1
			    println("NoOfActorsThatGotMessage: " + Main.NoOfActorsThatGotMessage)
			    timer.scheduleAtFixedRate(new java.util.TimerTask() {
				   def run(){
					   if (Main.NoOfActorsThatGotMessage == Main.nOfActors || (Main.network != Networks.FullNetwork && neighbours.length == 0)){	
					     timer.cancel
					     //println(self.path.name + " is done with rumors: " + nOfRumors)
					     nOfRumors += Main.rumorLimit + 1
			             mgr ! Dead
					   }
					   else{
					     var sentTo = 0
				         if (Main.network == Networks.FullNetwork)
				         {
				            val me = self.path.name.toInt
				         	while(sentTo == 0 || sentTo == me)
				        	{
				        	  sentTo = rnd.nextInt(Main.nOfActors+1)
				        	}
				            
				            //println(self.path.name + " is sending to " +  sentTo + " index: " + sentTo + " current len: " + neighbours.length)
				            val actor = context.system.actorSelection("akka://System/user/" + sentTo)
				    		actor ! Rumor
				         }
				         else
				         {
				        	//println(self.path.name + " is sending to " +  neighbours(sentTo) + " index: " + sentTo + " current len: " + neighbours.length)
			        	   var sent = false
				           while(!sent) {
					           try{
				        	    	sentTo = rnd.nextInt(neighbours.length)
				        	    	val actor = context.system.actorSelection("akka://System/user/" + neighbours(sentTo))
		        	    			actor ! Rumor
		        	    			sent = true
				        	    }
					        	catch{
					        	  case e: Exception => {
					        	    if (neighbours.length == 0){
					        	        sent = true
						        	    timer.cancel
									    nOfRumors += Main.rumorLimit + 1
							            mgr ! Dead
					        	    }
					        	  }
					        	}
				           }
				         } 
					   }
			       }
			    }, 100, 500);
        	}
        	nOfRumors += 1
        }
        else 
        {
          //println(self.path.name + " sending dead msg")
          sender ! Dead
          if (nOfRumors == Main.rumorLimit){
        	  timer.cancel
        	  //println(self.path.name + " is done with rumors: " + nOfRumors)
        	  mgr ! Dead
        	  nOfRumors += 1
          }
        }
      }
    case Dead =>
      {
        //println(self.path.name + " got dead msg from " + sender.path.name)
        if (Main.network != Networks.FullNetwork){
        	neighbours = neighbours.filter(x => x != sender.path.name)
        }
      }
  }
}